package com.admin.system.modules.quartz.service.impl;

import com.admin.common.exception.BadRequestException;
import com.admin.system.modules.quartz.QuartzManage;
import com.admin.system.modules.quartz.entity.QuartzJob;
import com.admin.system.modules.quartz.entity.QuartzLog;
import com.admin.system.modules.quartz.entity.dto.QuartzJobQueryDTO;
import com.admin.system.modules.quartz.mapper.QuartzJobMapper;
import com.admin.system.modules.quartz.mapper.QuartzLogMapper;
import com.admin.system.modules.quartz.service.QuartzJobService;
import com.admin.common.utils.StringUtils;
import com.admin.common.utils.PageResult;
import com.admin.common.utils.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import org.quartz.CronExpression;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * @author sq-lan
 */
@RequiredArgsConstructor
@Service(value = "quartzJobService")
public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob> implements QuartzJobService {

    private final QuartzLogMapper quartzLogMapper;
    private final QuartzManage quartzManage;

    @Override
    public PageResult<QuartzJob> paging(QuartzJobQueryDTO dto) {
        PageHelper.startPage(dto.getCurrent(), dto.getSize());
        return PageUtil.toPageHelper(this.list(dto));
    }

    @Override
    public List<QuartzJob> list(QuartzJobQueryDTO dto) {
        LambdaQueryWrapper<QuartzJob> wrapper = Wrappers.lambdaQuery();
        if (org.springframework.util.StringUtils.hasText(dto.getJobName())) {
            wrapper.like(QuartzJob::getJobName, dto.getJobName());
        }
        if (dto.getCreateTime() != null && !dto.getCreateTime().isEmpty()) {
            wrapper.between(QuartzJob::getCreateTime, dto.getCreateTime().get(0), dto.getCreateTime().get(1));
        }
        return this.list(wrapper);
    }

    @Override
    public PageResult<QuartzLog> pagingLog(QuartzJobQueryDTO dto) {
        PageHelper.startPage(dto.getCurrent(), dto.getSize());
        return PageUtil.toPageHelper(this.listLog(dto));
    }

    @Override
    public List<QuartzLog> listLog(QuartzJobQueryDTO dto) {
        LambdaQueryWrapper<QuartzLog> wrapper = Wrappers.lambdaQuery();
        if (org.springframework.util.StringUtils.hasText(dto.getJobName())) {
            wrapper.like(QuartzLog::getJobName, dto.getJobName());
        }
        if (dto.getIsSuccess() != null) {
            wrapper.eq(QuartzLog::getIsSuccess, dto.getIsSuccess());
        }
        if (dto.getCreateTime() != null && !dto.getCreateTime().isEmpty()) {
            wrapper.between(QuartzLog::getCreateTime, dto.getCreateTime().get(0), dto.getCreateTime().get(1));
        }
        return quartzLogMapper.selectList(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(QuartzJob entity) {
        if (!CronExpression.isValidExpression(entity.getCronExpression())) {
            throw new BadRequestException("cron表达式格式错误");
        }
        save(entity);
        quartzManage.addJob(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modify(QuartzJob entity) {
        if (!CronExpression.isValidExpression(entity.getCronExpression())) {
            throw new BadRequestException("cron表达式格式错误");
        }
        if (StringUtils.isNotBlank(entity.getSubTask())) {
            List<String> tasks = Arrays.asList(entity.getSubTask().split("[,，]"));
            if (tasks.contains(entity.getId().toString())) {
                throw new BadRequestException("子任务中不能添加当前任务ID");
            }
        }
        updateById(entity);
        quartzManage.updateJobCron(entity);
    }

    @Override
    public void updateIsPause(QuartzJob entity) {
        if (entity.getIsPause()) {
            quartzManage.resumeJob(entity);
            entity.setIsPause(false);
        } else {
            quartzManage.pauseJob(entity);
            entity.setIsPause(true);
        }
        updateById(entity);
    }

    @Override
    public void remove(Set<Integer> ids) {
        for (Integer id : ids) {
            QuartzJob quartzJob = getById(id);
            quartzManage.deleteJob(quartzJob);
        }
        removeByIds(ids);
    }

}
